//////////////////////////////////////////////////////////////////////
////                                                              ////
////  CFCECleaner.v                                               ////
////                                                              ////
////                                                              ////
////  This file is part of the "Pico E12" project                 ////
////  http://www.picocomputing.com                                ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2005, Picocomputing, Inc.                      ////
//// http://www.picocomputing.com/                                ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////////////////////////////////////////////////////////////////////JF

//This module cleans up the CE1 and CE2 signals. They have been known to fluctuate in the middle of transfers on some PCMCIA chipsets.

`timescale 10ns / 1ps

module CFCECleaner(CFClock, CE1_DIRTY, CE2_DIRTY, OE, WE, IORD, IOWR, CE1, CE2);

input CFClock;                                //200 MHz Free Running Clock
input CE1_DIRTY;                              //On some PCMCIA impliemntations the CE signals fluctuate in the middle of a transfer
input CE2_DIRTY;
input OE;                                     //Memory Output Enable
input WE;                                     //Memory Write Enable
input IORD;                                   //I/O Read
input IOWR;                                   //I/O Write

output CE1;                                   //Card Enable 1 (Clean)
output CE2;                                   //Card Enable 2 (Clean)

reg CE1_GATE;                                 //Registers for the Card Enable signals
reg CE2_GATE;
reg [2:0]CE1_HOLD;
reg [2:0]CE2_HOLD;

//synthesis attribute INIT of CE1_GATE is 1;
//synthesis attribute INIT of CE2_GATE is 1;

//synthesis attribute INIT of CE1_HOLD is 111;
//synthesis attribute INIT of CE2_HOLD is 111;

wire CEUnlocked;

assign CEUnlocked = ~((~OE) || (~WE) || (~IORD) || (~IOWR));     //Allow CE1 and CE2 to change states while not in a transfer

always @(CEUnlocked or CE1_DIRTY or CE2_DIRTY)
begin
   if (CEUnlocked) begin
	   CE1_GATE <= CE1_DIRTY;
		CE2_GATE <= CE2_DIRTY;
   end
end

//The following logic ensures that a one clock cycle long glitch does not make CE1 transition
always @(posedge CFClock)
begin
   if (CE1_DIRTY == 0) CE1_HOLD[2:0] <= 3'b0;
else
   CE1_HOLD[2:0] <= {CE1_HOLD[1:0], 1'b1};
end

always @(posedge CFClock)
begin
   if (CE2_DIRTY == 0) CE2_HOLD[2:0] <= 3'b0;
else
   CE2_HOLD[2:0] <= {CE2_HOLD[1:0], 1'b1};
end


assign CE1 = CE1_HOLD[2] && CE1_GATE;
assign CE2 = CE2_HOLD[2] && CE2_GATE;

endmodule				 